import requests
import os
import re
import threading
from multiprocessing import Queue
from collections import namedtuple
from urllib import error
from fake_useragent import UserAgent
#百度爬取图片地址:https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=tara%E9%AB%98%E6%B8%85%E5%A3%81%E7%BA%B8&pn=0
#word为你输入的需要查询的照片:例如你输入的tara高清图片
#pn为当前页面照片数量的第一张，在百度图片中，一页有20张图片，随意第二页的pn为20，因为从零开始的

Pn = 0
Num = 1
def search_img_count(url):
    #这里注意反扒机制，对某一些get请求需要构造请求头  from fake_useragent import UserAgent
    #如果出现请求不安全
    # pip install cryptography
    # pip install pyOpenSSL
    # pip install certifi
    try:
        ua = UserAgent()
        headers = {'User-Agent': ua.chrome}
        Response = requests.get(Url,headers=headers,verify=True,timeout=5)
    except error.HTTPError as e:
        print("请求出错:%s"%(e))
    else:
        if Response.status_code == 200:
            Html = Response.text
            #1.使用compile的正则
            Regex = re.compile('<div id="resultInfo" style="font-size: 13px;">找到相关图片约(?P<count>.*?)</div>',re.S)
            ImgCount= Regex.search(Html).group("count")
            return ImgCount
        else:
            raise "请求状态为:%s,请查找原因！！！"%(response.status_code)

#解析图片地址
def parase_img_url(Url,word,download_img_num,Img_Queue):
    global Num,Pn
    while True:
        try:
            ua = UserAgent()
            headers = {'User-Agent': ua.chrome}
            Response = requests.get(Url, headers=headers, verify=True, timeout=5)
        except error.HTTPError as e:
            print("请求出错:%s" % (e))
            break
        else:
            if Response.status_code == 200:

                Html = Response.text
                # 1.使用compile的正则
                Regex = re.compile('"objURL":"(?P<ImgUrl>.*?)",', re.S)
                img_path = Regex.finditer(Html)
                for i in img_path:
                    Img_Queue.put(i.group("ImgUrl"))
                    Num+=1
                    if Num>=download_img_num:
                        break#如果第一页的照片已经满足要求之后，结束当前的循环
                if Num==download_img_num:
                    break##下载完成之后结束
                else:
                    #如果第一页的照片无法满足要求继续第二页
                    Pn += 20
                    Url = "https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=" + word + "&pn=" + str(Pn)
            else:
                raise "请求状态为:%s,请查找原因！！！" % (response.status_code)

def down_load_img(SaveFilePath,download_img_num,word,Img_Queue):
    McNum = 0
    print("\033[0;36m开始下载......\033[0m")
    while True:
        try:
            ua = UserAgent()
            headers = {'User-Agent': ua.chrome}
            ImgUrl = Img_Queue.get(timeout=5)
            print("正在下载第%d张图片，图片地址:%s"%(McNum,ImgUrl))
            response = requests.get(ImgUrl,headers=headers,timeout=5)
            if response.status_code==200:
                img_content= response.content
                Mc = word+"_"+str(McNum)+".jpg"
                # ImgPath = os.path.join(SaveFilePath,Mc)
                ImgPath = SaveFilePath+"\\"+Mc
                with open(ImgPath,"wb") as f:
                    f.write(img_content)
            else:
                print("对不起，当前下载没有解析到图片或图片不存在")
            McNum+=1
            print(">>>>>",McNum)
            if McNum==download_img_num:
                break
        except BaseException as e:
            print(">>>>进入了这里？",e)
            if Img_Queue.qsize():
                continue
            else:break
    print("图片下载完成！！！！！")
if __name__ == '__main__':
    Crawler_Variable = namedtuple("Crawler_variable",["word"])
    Word = input('\033[5;32m请输入你需要查找图片的关键字(例如tara高清图片):\033[0m')
    Cv = Crawler_Variable(Word)
    #1.拼接请求百度图片搜索的地址
    Url = "https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word="+Cv.word+"&pn="+str(Pn)
    Img_count = search_img_count(Url)
    print('\033[0;35m您查找的类型:%s,搜索结果总共约有有%s\033[0m'%(Cv.word,Img_count))
    if Cv.word.__contains__("图片"):
        download_img_num = input("\033[1;32m请输入你需要爬取{word}的数量:\033[0m".format(word=Cv.word))
    else:
        download_img_num = input("\033[1;32m请输入你需要爬取{word}图片的数量:\033[0m".format(word=Cv.word))
    SaveFileName = input("\033[1;32m请输入保存图片的路径(输入文件夹名称即可，我们会在当前路径下创建):\033[0m")
    SaveFilePath = os.path.join(os.getcwd(),SaveFileName)
    if not os.path.exists(SaveFilePath):
        os.mkdir(SaveFilePath)
    Img_Queue = Queue()
    t1 = threading.Thread(target=parase_img_url,args=(Url,Cv.word,int(download_img_num),Img_Queue))
    t2 = threading.Thread(target=down_load_img,args=(SaveFilePath,int(download_img_num),Cv.word,Img_Queue))
    t2.start()
    t1.start()



